package com.atguigu.gmall.order.receiver;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.constant.MqConst;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.payment.client.PaymentFeignClient;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

@Component
@SuppressWarnings("all")
public class OrderReceiver {

    @Autowired
    private OrderService orderService;

    @Autowired
    private PaymentFeignClient paymentFeignClient;

    /**
     * 库存扣减成功，更新操作
     * @param strJson
     * @param message
     * @param channel
     */
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_WARE_ORDER,durable = "true",autoDelete = "false"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_WARE_ORDER,autoDelete = "false"),
            key = {MqConst.ROUTING_WARE_ORDER}
    ))
    public void stockOrderStatus(String strJson, Message message, Channel channel) {
        try {
            // 判断
            if (!StringUtils.isEmpty(strJson)) {
                // 转换数据类型
                Map<String,String> map = JSON.parseObject(strJson, Map.class);
                // 获取订单id
                String orderId = map.get("orderId");
                // 获取状态
                String status = map.get("status");
                // 判断是否扣减成功
                if ("DEDUCTED".equals(status)) {
                    this.orderService.updateOrderStatus(Long.parseLong(orderId),ProcessStatus.WAITING_DELEVER);
                } else {
                    this.orderService.updateOrderStatus(Long.parseLong(orderId),ProcessStatus.STOCK_EXCEPTION);
                    // 通知 管理员 或人工客户 或商家
                }
            }
        } catch (NumberFormatException e) {
            // 出现异常，邮件短信等通知
            e.printStackTrace();
        }

        // 手动确认
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    /**
     * 支付成功后，修改订单状态
     * @param orderId
     * @param message
     * @param channel
     */
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_PAYMENT_PAY,durable = "true",autoDelete = "false"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_PAYMENT_PAY,autoDelete = "false"),
            key = {MqConst.ROUTING_PAYMENT_PAY}
    ))
    public void paySuccess(Long orderId, Message message,Channel channel) {
        try {
            // 判断
            if (orderId != null) {
                // 查询状态
                // OrderInfo orderInfo = orderService.getById(orderId);
                OrderInfo orderInfo = orderService.getOrderInfoById(orderId);
                if (orderInfo != null && "UNPAID".equals(orderInfo.getOrderStatus())) {
                    // 修改状态
                    this.orderService.updateOrderStatus(orderId, ProcessStatus.PAID);

                    // 发送消息，扣减库存
                    this.orderService.sendOrderStatus(orderInfo);
                }
            }
        } catch (Exception e) {
            // 日志，短信通知
            e.printStackTrace();
        }
        // 手动确认
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    /**
     * 订单超时，判断订单状态
     *   已支付，不进行操作
     *   未支付，修改状态
     * @param orderId
     * @param message
     * @param channel
     */
    @SneakyThrows
    @RabbitListener(queues = MqConst.QUEUE_ORDER_CANCEL)
    public void cancelOrderStatus(Long orderId, Message message, Channel channel) {
        try {
            // 判断
            if (orderId != null) {
                // 查询订单，根据id
                // 1、先写查询订单的service，调用
                // 或
                // 2、使用通用service，继承接口，实现
                OrderInfo orderInfo = orderService.getById(orderId);
                // 判断是否为空
                if (orderInfo != null) {
                    // 获取状态进行判断
                    if ("UNPAID".equals(orderInfo.getOrderStatus()) && "UNPAID".equals(orderInfo.getProcessStatus())) {
                        // 查询支付记录信息--远程调用PaymentFeignClient
                        PaymentInfo paymentInfo = paymentFeignClient.getPaymentInfo(orderInfo.getOutTradeNo());
                        // 判断状态
                        if (paymentInfo != null && "UNPAID".equals(paymentInfo.getPaymentStatus())) {
                            // 查询支付宝支付记录
                            Boolean flag = paymentFeignClient.checkPayment(orderId);
                            // 判断
                            if (flag) {
                                // 有支付宝交易记录
                                Boolean result = paymentFeignClient.closePay(orderId);
                                // 判断
                                if (result) {
                                    // 即支付宝的交易，关闭成功，且未付款
                                    // 设置2表示：关闭订单，关闭支付记录
                                    orderService.execExpiredOrder(orderId,"2");
                                } else {
                                    // 有可能是已支付，不做处理
                                    // 说明已经付款了！ 正常付款成功都会走异步通知！
                                }
                            } else {
                                // 设置2表示：关闭订单，关闭支付记录
                                orderService.execExpiredOrder(orderId,"2");
                            }
                        } else {
                            // 没有支付记录，只关闭订单
                            // 有支付记录传2，没有支付记录传1
                            orderService.execExpiredOrder(orderId,"1");
                        }

                        // 时间格式化
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        System.out.println("消费者：消息接收时间：\t"+simpleDateFormat.format(new Date()));
                        System.out.println("订单超时：orderId=" + orderId);
                    }
                }
            }
        } catch (Exception e) {
            // 写入日志，数据库，短信
            e.printStackTrace();
        }

        // 手动确认消息
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
}
